package carassius.GUI.Calendar;

import carassius.BLL.DateTimeHelper;
import carassius.BLL.Events.ArrayListWithEvents;
import carassius.BLL.Events.Object.Added.ObjectAddedListener;
import carassius.BLL.Events.Object.ObjectEvent;
import carassius.BLL.Events.Object.Removed.ObjectRemovedListener;
import carassius.BLL.GregorianCalendarWithEvents;
import java.awt.Font;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.JToggleButton;
import javax.swing.UIManager;

/**
 *
 * @author siebz0r
 */
public class DayButton
		extends JToggleButton
		implements PropertyChangeListener,
				   ObjectAddedListener,
				   ObjectRemovedListener
{
	//<editor-fold defaultstate="collapsed" desc="Fields">
	private GregorianCalendar _date;
	private GregorianCalendarWithEvents _calendar;
	private ArrayListWithEvents<Long> _markedDates;
	private boolean _marked;
	//</editor-fold>

	//<editor-fold defaultstate="collapsed" desc="Constructors">
	public DayButton()
	{
		this(new GregorianCalendar(), new GregorianCalendarWithEvents(), new ArrayListWithEvents<Long>());
	}

	public DayButton(GregorianCalendar date,
					 GregorianCalendarWithEvents calendar,
					 ArrayListWithEvents<Long> markedDates)
	{
		super();
		_calendar = calendar;
		_markedDates = markedDates;
		setDate(date);
		setMarked(_markedDates.contains(_date.getTimeInMillis()));
		_calendar.addPropertyChangeListener("day", this);
		_markedDates.addObjectAddedListener(this);
		_markedDates.addObjectRemovedListener(this);
	}
	//</editor-fold>

	//<editor-fold defaultstate="collapsed" desc="Public Properties">
	public GregorianCalendar getDate()
	{
		return _date;
	}

	public void setDate(GregorianCalendar date)
	{
		_date = date;
		setLabel();
	}
	//</editor-fold>

	//<editor-fold defaultstate="collapsed" desc="Private Methods">
	private void setMarked(boolean marked)
	{
		_marked = marked;
		if (marked)
		{
			setFont(getFont().deriveFont(Font.BOLD));
		}
		else
		{
			setFont(getFont().deriveFont(Font.PLAIN));
		}
	}

	private void setLabel()
	{
		setText(Integer.toString(_date.get(GregorianCalendar.DAY_OF_MONTH)));
		setToolTipText(new SimpleDateFormat("dd-MMM-yyyy").format(new Date(_date.getTimeInMillis())));
		if (_date.get(GregorianCalendar.MONTH) == _calendar.get(GregorianCalendar.MONTH)
				&& _date.get(GregorianCalendar.YEAR) == _calendar.get(GregorianCalendar.YEAR))
		{
			if (_date.get(GregorianCalendar.DATE) == _calendar.get(GregorianCalendar.DATE))
			{
				setSelected(true);
			}
			else
			{
				setSelected(false);
			}
			//Adjust color so the button indicates it is in the active month
			setForeground(UIManager.getColor("Button.foreground"));
		}
		else
		{
			setSelected(false);
			//Adjust color so the button indicates it isn't in the active month
			setForeground(UIManager.getColor("Button.disabledText"));
		}
		setMarked(_markedDates.contains(_date.getTimeInMillis()));
	}
	//</editor-fold>

	@Override
	public void propertyChange(PropertyChangeEvent evt)
	{
		setSelected(DateTimeHelper.compareDates(_calendar, _date));
	}

	@Override
	public void objectAdded(ObjectEvent evt)
	{
		if (!_marked)
		{
			setMarked((Long) evt.getObject() == _date.getTimeInMillis());
		}
	}

	@Override
	public void objectRemoved(ObjectEvent evt)
	{
		if (_marked
				&& (Long) evt.getObject() == _date.getTimeInMillis())
		{
			setMarked(false);
		}
	}
}
